﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using AccountFormsCtrlLib;
using DevComponents.DotNetBar;
using DevelopStudio.Basic;
using System.IO;
using CommonManage = DevelopStudio.Common.Manage;
using CommonBasic = DevelopStudio.Common.Basic;
using DevelopStudio.Control;
using DevelopStudio.Control.FormPage;
using DevelopStudio.Control.Commit;
using DevComponents.DotNetBar.Controls;

namespace DevelopStudio
{
    public partial class WorkPlatform : ControlBase
    {
        private ChangelistInfo changelistInfo;

        public ChangelistInfo ChangelistInfo
        {
            get
            {
                return this.changelistInfo;
            }

            set
            {
                if (value == null)
                {
                    MessageBox.Show(Properties.Resources.ErrorNullChangelistInPlatform);
                    return;
                }

                if (value.Status == (int)AppEnum.ChangelistStatus.ReceiveReviewing)
                {
                    MessageBox.Show(Properties.Resources.ErrorAddCodeReviewChangelistToWorkPlatform);
                    return;
                }

                if (this.changelistInfo != value)
                {
                    if (this.changelistInfo != null)
                    {
                        this.changelistInfo.StatusChanged -= changelistInfo_StatusChanged;
                        this.changelistInfo.ErrorStatusChanged -= changelistInfo_ErrorCodeChanged;
                    }

                    this.changelistInfo = value;
                    this.changelistInfo.StatusChanged += changelistInfo_StatusChanged;
                    this.changelistInfo.ErrorStatusChanged += changelistInfo_ErrorCodeChanged;
                    this.labelChangelistTitle.Text = this.changelistInfo.Name;
                    this.toolTip.SetToolTip(this.labelChangelistTitle, this.labelChangelistTitle.Text);
                    this.labelPlatform.Text = this.changelistInfo.WorkingCopyPath;
                    this.toolTip.SetToolTip(this.labelPlatform, this.labelPlatform.Text);
                    this.StatusChanged(this.changelistInfo);
                    this.ErrorCodeChanged(this.changelistInfo);
                    this.DisplayBugs();
                }
            }
        }

        void changelistInfo_ErrorCodeChanged(object sender, CommonBasic.StatusEventArgs e)
        {
            ChangelistInfo owner = sender as ChangelistInfo;

            this.Invoke(new Action(() =>
                {
                    if (owner != this.changelistInfo)
                    {
                        throw new InvalidDataException(Properties.Resources.ExceptionHandler);
                    }

                    this.ErrorCodeChanged(owner);
                }));
        }

        void WorkPlatform_Load(object sender, System.EventArgs e)
        {
            this.pictureBoxError.Image = new Bitmap(Properties.Resources.critical.ToBitmap(), new Size(16, 16));
        }

        private void ErrorCodeChanged(ChangelistInfo changelist)
        {
            switch (changelist.ErrorInfo.ErrorCode)
            {
                case AppEnum.ChangelistErrorCode.BugAssigned:
                    {
                        this.buttonAssignBug.Enabled = true;
                        this.buttonCodeReview.Enabled = false;
                        this.buttonPack.Enabled = true;
                        this.buttonSubmit.Enabled = false;
                        this.buttonComment.Visible = false;
                    }
                    break;
                case AppEnum.ChangelistErrorCode.CodeReview:
                    {
                        this.buttonAssignBug.Enabled = true;
                        this.buttonCodeReview.Enabled = false;
                        this.buttonPack.Enabled = true;
                        this.buttonSubmit.Enabled = false;
                        this.buttonComment.Visible = false;
                    }
                    break;
                default:
                    break;
            }

            if (changelist.ErrorInfo.ErrorCode == AppEnum.ChangelistErrorCode.None)
            {
                this.panelError.Visible = false;
                this.labelErrorText.Text = string.Empty;
            }
            else
            {
                this.panelError.Visible = true;
                this.labelErrorText.Text = changelistInfo.ErrorInfo.Message;
            }

            this.toolTip.SetToolTip(this.labelErrorText, this.labelErrorText.Text);
        }

        private void StatusChanged(ChangelistInfo changelist)
        {
            switch (changelist.Status)
            {
                case (int)AppEnum.ChangelistStatus.Local:
                    {
                        this.buttonAssignBug.Enabled = true;
                        this.buttonCodeReview.Enabled = true;
                        this.buttonPack.Enabled = true;
                        this.buttonSubmit.Enabled = false;
                        this.buttonComment.Visible = false;
                    }
                    break;
                case (int)AppEnum.ChangelistStatus.Rejected:
                    {
                        this.buttonAssignBug.Enabled = true;
                        this.buttonCodeReview.Enabled = true;
                        this.buttonPack.Enabled = true;
                        this.buttonSubmit.Enabled = false;
                        this.buttonComment.Visible = true;
                    }
                    break;
                case (int)AppEnum.ChangelistStatus.CanceledReview:
                    {
                        this.buttonAssignBug.Enabled = true;
                        this.buttonCodeReview.Enabled = true;
                        this.buttonPack.Enabled = true;
                        this.buttonSubmit.Enabled = false;
                        this.buttonComment.Visible = false;
                    }
                    break;
                case (int)AppEnum.ChangelistStatus.SendReviewing:
                    {
                        this.buttonAssignBug.Enabled = false;
                        this.buttonCodeReview.Enabled = true;
                        this.buttonPack.Enabled = true;
                        this.buttonSubmit.Enabled = false;
                        this.buttonComment.Visible = false;
                    }
                    break;
                case (int)AppEnum.ChangelistStatus.Approved:
                    {
                        this.buttonAssignBug.Enabled = true;
                        this.buttonCodeReview.Enabled = true;
                        this.buttonPack.Enabled = true;
                        this.buttonSubmit.Enabled = true;
                        this.buttonComment.Visible = false;
                    }
                    break;
                case (int)AppEnum.ChangelistStatus.ApprovedWithComment:
                    {
                        this.buttonAssignBug.Enabled = true;
                        this.buttonCodeReview.Enabled = true;
                        this.buttonPack.Enabled = true;
                        this.buttonSubmit.Enabled = true;
                        this.buttonComment.Visible = true;
                    }
                    break;
                case (int)AppEnum.ChangelistStatus.Disabled:
                    {
                        this.buttonAssignBug.Enabled = true;
                        this.buttonCodeReview.Enabled = true;
                        this.buttonPack.Enabled = true;
                        this.buttonSubmit.Enabled = false;
                        this.checkBoxHide.Checked = true;
                        this.buttonComment.Visible = false;
                    }
                    break;
                case (int)AppEnum.ChangelistStatus.CommitedButWaiting:
                    {
                        Utility.Settings.WorkingCopies.Find(o => o.Path == this.ChangelistInfo.WorkingCopyPath).ChangelistInfos.Remove(this.ChangelistInfo);
                        Utility.SaveEnvironmentSettings();
                    }
                    break;
                case (int)AppEnum.ChangelistStatus.Commited:
                    {
                        this.OnDisplayChanged(this, new CommonBasic.StatusEventArgs(false, true));
                    }
                    break;
                default:
                    {
                        MessageBox.Show(Properties.Resources.ErrorAddCodeReviewChangelistToWorkPlatform);
                        return;
                    }
            }

            if (changelist.Status == (int)AppEnum.ChangelistStatus.SendReviewing)
            {
                this.buttonCodeReview.Text = Properties.Resources.CancelReview;
            }
            else
            {
                this.buttonCodeReview.Text = Properties.Resources.CodeReview;
            }

            if (this.changelistInfo.BugInfos.Count <= 0)
            {
                this.buttonCodeReview.Enabled = false;
            }

            this.labelXStatus.Text = string.Format(Properties.Resources.ChangelistTitle, AppEnum.GetDescription(typeof(AppEnum.ChangelistStatus), changelist.Status));
            this.toolTip.SetToolTip(this.labelXStatus, this.labelXStatus.Text);
        }

        protected void changelistInfo_StatusChanged(object sender, CommonBasic.StatusEventArgs e)
        {
            ChangelistInfo owner = sender as ChangelistInfo;

            this.Invoke(new Action(() =>
                {
                    if (owner != this.changelistInfo)
                    {
                        throw new InvalidDataException(Properties.Resources.ExceptionHandler);
                    }

                    this.StatusChanged(owner);
                }));
        }

        public WorkPlatform()
        {
            InitializeComponent();
        }

        public bool ExpandBugBar
        {
            get
            {
                return this.expandableSplitter.Expanded;
            }

            set
            {
                if (this.expandableSplitter.Expanded != value)
                {
                    this.expandableSplitter.Expanded = value;
                }
            }
        }

        protected void expandableSplitter1_ExpandedChanged(object sender, DevComponents.DotNetBar.ExpandedChangeEventArgs e)
        {
            PanelEx panel = this.expandableSplitter.Parent as PanelEx;

            if (panel == null)
            {
                return;
            }

            int sizeOffset = this.dataGridViewX1.Height;

            if (e.NewExpandedValue == true)
            {
                this.Height += sizeOffset;
            }
            else
            {
                this.Height -= sizeOffset;
            }

            this.OnExpandedChanged(this, new ExpandedChangeEventArgsEx(e.EventSource, e.NewExpandedValue) { SizeOffset = sizeOffset });
        }

        private void checkBoxHide_CheckedChangedEx(object sender, CheckBoxXChangeEventArgs e)
        {
            if (e.NewChecked != null)
            {
                if (changelistInfo.Displayed == e.NewChecked.Checked)
                {
                    changelistInfo.Displayed = !e.NewChecked.Checked;
                    Utility.SaveEnvironmentSettings();
                }
            }

            this.OnDisplayChanged(this, new CommonBasic.StatusEventArgs(e.OldChecked == null ? false : e.OldChecked.Checked, e.NewChecked.Checked));
        }

        private void buttonAssignBug_Click(object sender, EventArgs e)
        {
            try
            {
                using (AssignBugForm dlg = new AssignBugForm(this.changelistInfo))
                {
                    if (dlg.ShowDialog() == DialogResult.Cancel)
                    {
                        return;
                    }
                }

                this.DisplayBugs();
            }
            catch (Exception ex)
            {
                MessageBox.Show(Utility.TraceException(ex), this.ParentForm.Text);
                return;
            }
        }

        private void DisplayBugs()
        {
            /*
            var data = from t in this.changelistInfo.BugInfos
                       select new
                        {
                            ID = t.ID,
                            Subject = t.Subject,
                            Description = t.Description,
                            Status = t.Status.Name,
                            AssignedTo = t.AssignedTo.Name
                        };

            this.dataGridViewX1.DataSource = data.ToList();
             * */

            this.dataGridViewX1.Rows.Clear();

            foreach (BugInfo var in this.changelistInfo.BugInfos)
            {
                this.dataGridViewX1.Rows.Add(new string[] {var.ID.ToString(), var.Subject, var.Description, var.Status.Name, var.AssignedTo.Name});
            }

            if (this.changelistInfo.BugInfos.Count <= 0)
            {
                this.buttonCodeReview.Enabled = false;
            }
            else
            {
                this.buttonCodeReview.Enabled = true;
            }

            this.buttonAssignBug.Text = string.Format(Properties.Resources.AssignBugs, this.changelistInfo.BugInfos.Count);
        }

        private void buttonViewChange_Click(object sender, EventArgs e)
        {
            try
            {
                string execFileFullPath = Path.Combine(Application.StartupPath, AppConst.DiffToolPath);
                string fileFullName = Path.GetTempFileName() + CommonBasic.AppConst.DiffToolFileSuffix;

                if (Utility.PackageDiffInfo(this.changelistInfo, fileFullName) == false)
                {
                    MessageBox.Show(string.Format(Properties.Resources.ErrorPackageToFile, fileFullName));
                    return;
                }

                Utility.ExecuteCmd(execFileFullPath, fileFullName);
            }
            catch (Exception ex)
            {
                MessageBox.Show(Utility.TraceException(ex), this.ParentForm.Text);
                return;
            }
        }

        private void buttonCodeReview_Click(object sender, EventArgs e)
        {
            try
            {
                if (this.ChangelistInfo.Status != (int)AppEnum.ChangelistStatus.SendReviewing)
                {
                    using (SendCodeReviewForm dlg = new SendCodeReviewForm(this.changelistInfo))
                    {
                        if (dlg.ShowDialog() != DialogResult.OK)
                        {
                            return;
                        }
                    }
                }
                else
                {
                    if (MessageBox.Show(Properties.Resources.ConfirmCancelCodeReviewContent, Properties.Resources.ConfirmCaption, MessageBoxButtons.YesNoCancel, MessageBoxIcon.Information)
                        != DialogResult.Yes)
                    {
                        return;
                    }

                    this.CancelCodeReview();
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(Utility.TraceException(ex), this.ParentForm.Text);
                return;
            }
        }

        private void CancelCodeReview()
        {
            List<BugInfo> thisBugs = new List<BugInfo>();

            foreach (BugInfo var in this.ChangelistInfo.BugInfos)
            {
                BugInfo temp = Utility.GetBugInfo(var.ID.ToString());

                if (temp == null)
                {
                    MessageBox.Show(string.Format(Properties.Resources.ErrorGetBugsInfo, var.ID));
                    return;
                }

                IdNamePair reviewReviewer = var.CustomFields.Find(o => o.ID == "31");

                if (temp.AssignedTo.ID == Utility.Settings.MyInfo.ID &&
                    reviewReviewer.Value != Utility.Settings.MyInfo.ID)
                {
                    MessageBox.Show(string.Format(Properties.Resources.WarningIsYourBugs, var.ID));
                    return;
                }

                thisBugs.Add(temp);
            }

            foreach (BugInfo var in thisBugs)
            {
                var.AssignedTo = new IdNamePair() { ID = Utility.Settings.MyInfo.ID, Name = Utility.Settings.MyInfo.Name };
                if (var.UpdateRedmine(this.ChangelistInfo, AppEnum.ChangelistStatus.CanceledReview) == false)
                {
                    MessageBox.Show(string.Format(Properties.Resources.ErrorUpdateBugs, var.ID));
                    continue;
                }
            }

            this.ChangelistInfo.BugInfos.Clear();
            this.ChangelistInfo.BugInfos.AddRange(thisBugs);
            this.ChangelistInfo.Status = (int)AppEnum.ChangelistStatus.CanceledReview;

            Utility.SaveEnvironmentSettings();
        }

        private void buttonPack_Click(object sender, EventArgs e)
        {
            string fileFullName = string.Empty;
            string fileName = string.Empty;
            this.ChangelistInfo.BugInfos.ForEach(o => fileName += "_" + o.ID);

            using (SaveFileDialog dlg = new SaveFileDialog())
            {
                dlg.Filter = "(*.dsdiff)|*.dsdiff";
                dlg.FileName = fileName;
                if (dlg.ShowDialog() != DialogResult.OK)
                {
                    return;
                }

                fileFullName = dlg.FileName;
            }

            try
            {
                if (Utility.PackageDiffInfo(this.changelistInfo, fileFullName, false) == false)
                {
                    MessageBox.Show(string.Format(Properties.Resources.ErrorPackageToFile, fileFullName));
                    return;
                }

                this.changelistInfo.StoredPath = fileFullName;
                Utility.SaveEnvironmentSettings();
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
                return;
            }
        }

        private void buttonSubmit_Click(object sender, EventArgs e)
        {
            try
            {
                using (CommitForm wizard = new CommitForm(this.ChangelistInfo))
                {
                    wizard.ShowDialog();
                }

                if (this.ChangelistInfo.Status == (int)AppEnum.ChangelistStatus.CommitedButWaiting)
                {
                    this.ChangelistInfo.Status = (int)AppEnum.ChangelistStatus.Commited;
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(Utility.TraceException(ex), this.ParentForm.Text);
                return;
            }
        }

        private void buttonComment_Click(object sender, EventArgs e)
        {
            try
            {
                using (ViewFeedbackComment dlg = new ViewFeedbackComment(this.ChangelistInfo))
                {
                    dlg.ShowDialog();
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(Utility.TraceException(ex), this.ParentForm.Text);
                return;
            }
        }
    }
}
